import re

from django.conf import settings
from django.core.mail import send_mail
from django_redis import get_redis_connection
from rest_framework import serializers
from users.models import User

from celery_tasks.email.tasks import send_email

from itsdangerous import TimedJSONWebSignatureSerializer as TJS

class UserSerializer(serializers.ModelSerializer):
    # 显示指明模型类的字段
    password2 = serializers.CharField(max_length=20,min_length=8,write_only=True)
    sms_code = serializers.CharField(min_length=6,max_length=6,write_only=True)
    allow = serializers.CharField(write_only=True)
    token = serializers.CharField(read_only=True)

    class Meta:
        model = User
        fields = ("mobile","username","password","sms_code","allow","password2","id","token")
        # 额外参数设置
        extra_kwargs={
            "password":{
                "write_only":True,
                "min_length":8,
                "max_length":20,
            },
            "username":{
                "min_length": 5,
                "max_length": 20,
            }
        }

    # 验证手机号格式
    def validate_mobile(self, value):
        if not re.match(r"^1[3-9]\d{9}$",value):
            raise serializers.ValidationError("手机号格式不正确")

        return value
    # 验证协议
    def validate_allow(self,value):
        if value != 'true':
            raise serializers.ValidationError("没有勾选协议")
        return value

    # 验证密码和短信验证码
    def validate(self, attrs):
        print(attrs)
        # 密码验证
        if attrs["password"] != attrs["password2"]:
            raise serializers.ValidationError("密码不正确")
        # 短信验证码验证
        # 通过手机号获取redis 存储的短信验证码
        # 比较两个验证码是否正确
        coon = get_redis_connection("sms_code")
        real_sms_code = coon.get("sms_code_%s"%attrs["mobile"])
        # 这个短信验证码是二进制数据
        if not real_sms_code:
            raise serializers.ValidationError("短信验证码失效")

        if real_sms_code.decode() != attrs["sms_code"]:
            raise serializers.ValidationError("短信验证码不正确")
        return attrs

    def create(self, validated_data):

        del validated_data["password2"]
        del validated_data["sms_code"]
        del validated_data["allow"]
        # 使用模型类进行保存
        user = User.objects.create_user(**validated_data)

        # 手动创建令牌
        from rest_framework_jwt.settings import api_settings
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        # 生成载荷部分
        payload = jwt_payload_handler(user)
        # 生成tocken
        token = jwt_encode_handler(payload)
        # 对对象添加属性
        user.token = token
        # 将保存后的数据进行返回
        return user

class UserDetailSerializer(serializers.ModelSerializer):
    """
    用户个人中中心信息展示序列化器
    """
    class Meta:
        model = User
        exclude = ("password",)

class UserUpdateSerializer(serializers.ModelSerializer):
    """
    邮箱更新序列化器
    """
    class Meta:
        model = User
        fields = ("email",)

    def update(self, instance, validated_data):
        instance.email = validated_data["email"]
        instance.save()

        tjs = TJS(settings.SECRET_KEY,60*60)
        token = tjs.dumps({"name":instance.username}).decode()

        subject = "美多商城邮箱验证"
        verify_url = 'http://www.meiduo.site:8080/success_verify_email.html?token=' + token
        html_message = '<p>尊敬的用户您好！</p>' \
                       '<p>感谢您使用美多商城。</p>' \
                       '<p>您的邮箱为：%s 。请点击此链接激活您的邮箱：</p>' \
                       '<p><a href="%s">%s<a></p>' % (validated_data['email'], verify_url, verify_url)

        # send_mail 参数 第一个是标题，第二个参数为邮箱内容，不支持标签第三个参数为收件人看到的发件人的信息，第四个参数是收件人列表
        # send_mail(subject,"",settings.EMAIL_FROM,[validated_data["email"]],html_message=html_message)
        send_email.delay(subject,validated_data["email"],html_message)
        return instance



